package com.spic.business.violation.supervision.speed.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import com.spic.business.alarm.constant.CommonConstant;
import com.spic.business.alarm.utils.HttpClientUtil;
import com.spic.business.common.core.workflow.IWorkFlowType;
import com.spic.business.common.workflow.WorkFlowServiceImpl;
import com.spic.business.enumconst.BusinessType;
import com.spic.business.hik.constant.HkConstant;
import com.spic.business.vehicle.domain.VehicleManagement;
import com.spic.business.vehicle.mapper.VehicleManagementMapper;
import com.spic.business.violation.supervision.speed.domain.*;
import com.spic.business.violation.supervision.speed.mapper.GetHkPersonMapper;
import com.spic.business.violation.supervision.speed.mapper.GetHkVehicleMapper;
import com.spic.business.violation.supervision.speed.mapper.ViolationsSpeedRecordMapper;
import com.spic.business.violation.supervision.speed.mapper.ViolationsSpeedRecordVoMapper;
import com.spic.business.violation.supervision.speed.service.IGetHkService;
import com.spic.common.core.constant.SecurityConstants;
import com.spic.common.core.domain.R;
import com.spic.common.core.utils.DateUtils;
import com.spic.common.core.utils.StringUtils;
import com.spic.system.api.RemoteFileService;
import com.spic.system.api.RemoteUserService;
import com.spic.system.api.domain.FileDomain;
import com.spic.system.api.domain.SysUser;
import com.spic.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 获取海康数据Service业务层处理
 *
 * @author wenzhaolong
 * @date 20212-03-10
 */
@Service
public class GetHkServiceImpl extends WorkFlowServiceImpl<ViolationsSpeedRecordMapper, ViolationsSpeedRecord> implements IGetHkService {

    private static final Logger log = LoggerFactory.getLogger(GetHkServiceImpl.class);

    @Autowired
    private ThreadPoolExecutor executor;

    @Autowired
    private GetHkPersonMapper getHkPersonMapper;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private GetHkVehicleMapper getHkVehicleMapper;

    @Autowired
    private ViolationsSpeedRecordVoMapper violationsSpeedRecordVoMapper;

    @Autowired
    private RemoteFileService remoteFileService;

    @Autowired
    private VehicleManagementMapper vehicleManagementMapper;

    /**
     * 获取海康人员信息
     * @return 结果集
     */
    @Override
    public JSONArray personList() {
        JSONArray person = this.getHikVehicle(HkConstant.HK_PERSON_PATH);
        this.saveHkPerson(person);
        return person;
    }

    /**
     * 插入人员信息表
     * @param person 人员列表
     */
    public void saveHkPerson(JSONArray person){
        executor.execute(() -> {
            List<HkPerson> list = person.toJavaList(HkPerson.class);
            getHkPersonMapper.deleteTable();
            getHkPersonMapper.insertBatch(list);
        });
    }

    /**
     * 获取海康车辆信息
     * @return 结果集
     */
    @Override
    public JSONArray vehicleList() {
        JSONArray vehicle = this.getHikVehicle(HkConstant.HK_VEHICLE_PATH);
        this.saveHkVehicle(vehicle);
        return vehicle;
    }

    /**
     * 插入车辆信息表
     * @param vehicle 车辆信息列表
     */
    public void saveHkVehicle(JSONArray vehicle){
        executor.execute(() -> {
            List<HkVehicle> list = vehicle.toJavaList(HkVehicle.class);
            getHkVehicleMapper.deleteTable();
            getHkVehicleMapper.insertBatch(list);
        });
    }

    /**
     * 插入测速数据
     * @param list 请求参数
     * @return 结果
     */
    @Override
    public int saveSpeedData(List<ViolationsSpeedRecordVo> list) {
        try{
            this.saveViolationsSpeedRecordList(list);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
        return 1;
    }
    /**
     * 防疲劳车辆告警数据
     */

    @Override
    public int saveFplAlarmData()
    {
        try
        {
                List<ViolationsSpeedRecordVo> list = new ArrayList<>();
                String postUrl = "https://"+ CommonConstant.ROMA_HOST +"/api/car/queryAlarmDetail";
                Map<String, String> contentMap = new HashMap<>();
                contentMap.put("begintime",DateUtils.getZeroDateTime());
                contentMap.put("endtime",DateUtils.getTime());
                contentMap.put("currentPage","1");
                contentMap.put("pageRecords","1000");
                contentMap.put("armType","11,49,620,621,622,623,624,625,626,627");
                String jsonStr = HttpClientUtil.postMap(postUrl,null,contentMap);
                JSONObject resultJson = JSONObject.parseObject(jsonStr);
                JSONArray jsonArray = resultJson.getJSONArray("alarms");
                List<FplAlarmSpeedDTO>  spicList= jsonArray.toJavaList(FplAlarmSpeedDTO.class);
                log.info(spicList.toString());
                for(FplAlarmSpeedDTO f :spicList){
                    Long cid = violationsSpeedRecordVoMapper.selectViolationsSpeedRecordByFplId(f.getGuid());
                    //存在数据则不插入
                    if (StringUtils.isNotNull(cid)) { continue; }
                    ViolationsSpeedRecordVo v = new ViolationsSpeedRecordVo();
                    v.setVehicleNumber(f.getVid().trim());
                    v.setIllegalTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",f.getBTimeStr()));
                    v.setFplId(f.getGuid());
                    String ssp = f.getSsp();
                    if(StringUtils.isNotEmpty(ssp)){
                        double v1 = Double.parseDouble(ssp);
                        double sp = v1/10d;
                        v.setRunningSpeed(sp);//超速速度
                    }
                    v.setIllegalInstructions(f.getAtpStr());
                    v.setDataType("防疲劳");
                    v.setCreateBy("1");//创建人
                    v.setPenaltyAmount(300d);//罚款金额
                    v.setIllegalArea("1");//矿区
                    v.setIllegalType("1");//作业类违章

                    String atp = f.getAtp();
                    if(StringUtils.isNotEmpty(atp)){
                        if("11".equals(atp)){ //超速
                            v.setIllegalSources("0");//超速为0
                        } else if("49".equals(atp)){ //防疲劳
                            v.setIllegalSources("2");//防疲劳为2
                        } else if ("620".equals(atp) || "621".equals(atp)){
                            v.setIllegalSources("3");
                        } else if ("622".equals(atp) || "623".equals(atp)) {
                            v.setIllegalSources("4");
                        } else if ("624".equals(atp) || "625".equals(atp)){
                            v.setIllegalSources("5");
                        } else if ("626".equals(atp) || "627".equals(atp)){
                            v.setIllegalSources("6");
                        }
                    }


                    if (v.getVehicleNumber() != null) {
                        //超速
                        VehicleManagement vehicleManagement = new VehicleManagement();
                        vehicleManagement.setPlateno(v.getVehicleNumber().trim());
                        vehicleManagement.setState("0");
                        List<VehicleManagement> carList = vehicleManagementMapper.selectVehicleManagementList(vehicleManagement);
                        if(carList.size() == 0) {
                            violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                        } else {
                            if(carList.get(0).getManageDept() == null) {
                                violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                            } else {
                                v.setAssociatedDept(String.valueOf(carList.get(0).getManageDept()));
                                v.setVehicleUnit(String.valueOf(carList.get(0).getUnit()));
                                v.setResponsible(carList.get(0).getDriverName());
                                violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                                this.startInstance(v.getId());
                            }
                        }
                    } else {
                        violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                    }

//                    Map<String, Object> map = this.getDeptId(v.getVehicleNumber());
//                    if(StringUtils.isNull(map) || StringUtils.isNull(map.get("deptId")) || StringUtils.isNull(map.get("userId"))){
//                        continue;
//                    }
//                    v.setAssociatedDept(map.get("deptId").toString());//部门
//                    v.setResponsible(map.get("userId").toString());//人员
//                    this.startInstance(v.getId());
                }
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
            return 1;
        }

    /**
     * 循环新增违章数据，并发起流程
     * @param list 请求参数集合
     */
    public void saveViolationsSpeedRecordList(List<ViolationsSpeedRecordVo> list){
        for(ViolationsSpeedRecordVo v : list){
            if (StringUtils.isNotEmpty(v.getIllegalSources()) && v.getIllegalSources().equals("1")){//未带安全帽
                String imageUrl = v.getAssociatedAttachments();
                if (imageUrl.startsWith("http")) {//图片地址为http地址
                    //上传minio
                    FileDomain file = new FileDomain();
                    file.setFileUrl(imageUrl);
                    file.setFileName(v.getRoadName() +"_未带安全帽违章抓拍_"+ System.currentTimeMillis() + ".jpg");
                    file.setBucketName("nohelmet");
                    file.setContentType("image/jpeg");
                    String url = remoteFileService.uploadOfFilePath(file).getData();
                    v.setAssociatedAttachments(url);//海康抓拍告警-未带安全帽截图地址
                }
            } else {//超速
                //已存在记录则跳过
                Long cid = violationsSpeedRecordVoMapper.selectViolationsSpeedRecordById(v.getCid());
                //存在数据则不插入
                if (StringUtils.isNotNull(cid)) { continue; }
                v.setAssociatedAttachments(HkConstant.CS_URL+v.getAssociatedAttachments());//超速截图地址
                v.setVehicleNumber(v.getVehicleNumber().trim());
                //时间减去8小时
                log.info("========v.getIllegalTime() before============> "+v.getIllegalTime());
                long time = v.getIllegalTime().getTime() - 8*3600*1000 ;
                v.setIllegalTime(DateUtils.parseDate(DateUtils.timestampToDateStr(time)));
                log.info("========v.getIllegalTime() after============> "+v.getIllegalTime());
    //            Map<String, Object> map = this.getDeptId(v.getVehicleNumber());
    //            if(StringUtils.isNull(map) || StringUtils.isNull(map.get("deptId")) ||
    //                StringUtils.isNull(map.get("userId"))){
    //                continue;
    //            }
    //            v.setAssociatedDept(map.get("deptId").toString());//部门
    //            v.setResponsible(map.get("userId").toString());//人员
                v.setIllegalSources("0");//超速为0
            }
            v.setCreateTime(DateUtils.getNowDate());//创建时间
            v.setCreateBy("1");//创建人
            v.setRoadName(v.getRoadName());//测点
            v.setPenaltyAmount(300d);//罚款金额
            v.setIllegalArea("1");//矿区
            v.setIllegalType("1");//作业类违章
            v.setDataType("定点测速");

            if (v.getVehicleNumber() != null) {
                //超速
                VehicleManagement vehicleManagement = new VehicleManagement();
                vehicleManagement.setPlateno(v.getVehicleNumber().trim());
                vehicleManagement.setState("0");
                List<VehicleManagement> carList = vehicleManagementMapper.selectVehicleManagementList(vehicleManagement);
                if(carList.size() == 0) {
                    violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                } else {
                    if(carList.get(0).getManageDept() == null) {
                        violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                    } else {
                        v.setAssociatedDept(String.valueOf(carList.get(0).getManageDept()));
                        v.setVehicleUnit(String.valueOf(carList.get(0).getUnit()));
                        v.setResponsible(carList.get(0).getDriverName());
                        violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
                        this.startInstance(v.getId());
                    }
                }
            } else {
                v.setDataType("视频监控");
                //未戴安全帽
                violationsSpeedRecordVoMapper.insertViolationsSpeedRecordVo(v);
            }
        }
    }

    /**
     * 发起违章行为流程
     * @param id 表单数据id
     */
    public void startInstance(Long id){
        executor.execute(() -> {
            startFlow(id.toString());
        });
    }

    /**
     * 获取部门违章管理员id
     * @param deptId 部门id
     * @return 人员id
     */
    public Long getDrafter(String deptId){
        R<SysUser> user = remoteUserService.getWzUserId(deptId);
        return user.getData().getUserId();
    }

    /**
     * 获取工作流程变量
     * @return IWorkFlowType
     */
    @Override
    protected IWorkFlowType getWorkFlowType() {
        return BusinessType.SPEED;
    }

    @Override
    protected void setWorkFlowVariable(ViolationsSpeedRecord entity, Map<String, Object> variable) {
        String associatedDept = entity.getAssociatedDept();
        variable.put("carmanger", getDrafter(associatedDept));
    }

    /**
     * 通过车牌号查询海康车辆人员数据，返回车辆对应人员的部门id，人员id
     * @param vehicleNo 车牌号
     * @return 部门id
     */
    public Map<String, Object> getDeptId(String vehicleNo){
        Map<String, Object> map = new HashMap<>();
        String userName = getHkVehicleMapper.selectUserNameByVehicleNo(vehicleNo);
        if(StringUtils.isEmpty(userName)){
            return null;
        }
        R<LoginUser> loginUser = remoteUserService.getUserInfo(userName,SecurityConstants.INNER);
        map.put("userId",loginUser.getData().getSysUser().getUserId());
        map.put("deptId",loginUser.getData().getSysUser().getDeptId());
        return map;
    }

    /**
     * 查询海康平台数据列表
     * @param url 请求接口service
     * @return array结果集
     */
    private JSONArray getHikVehicle(String url) {
        JSONArray jsonArray = new JSONArray();
        Map<String, String> path = new HashMap<String, String>(2);
        path.put("https://", url);
        Map<String,Object> map = this.getPageList(path,1);
        JSONArray listArr = JSONObject.parseArray(map.get("listArr").toString());
        jsonArray.addAll(listArr);
        int total = Integer.parseInt(map.get("total").toString());
        int n = Math.floorDiv(total, 1000) + 1;
        for(int i=2;i<=n;i++){
            Map<String,Object> pageMap = this.getPageList(path,i);
            JSONArray pageList = JSONObject.parseArray(pageMap.get("listArr").toString());
            if(StringUtils.isNotNull(pageList) && pageList.size()>0){
                jsonArray.addAll(pageList);
            }
        }
        return jsonArray;
    }

    /**
     * 调用SDK获取分页数据
     * @param path 请求地址
     * @param pageNo pageNumber
     * @return 结果集
     */
    public Map<String,Object> getPageList(Map<String, String> path,int pageNo){
        ArtemisConfig.host = HkConstant.HK_HOST;
        ArtemisConfig.appKey = HkConstant.HK_AK;
        ArtemisConfig.appSecret = HkConstant.HK_SK;

        Map<String,Object> map = new HashMap<String,Object>();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("pageNo", pageNo);
        jsonObject.put("pageSize", 1000);
        String result = ArtemisHttpUtil.doPostStringArtemis(path,jsonObject.toJSONString(),
                null,null,"application/json",null);
        JSONObject responseStr = JSONObject.parseObject(result);
        String data = responseStr.getString("data");
        JSONObject dataJson = JSONObject.parseObject(data);
        int total = dataJson.getIntValue("total");
        JSONArray listArr = dataJson.getJSONArray("list");
        map.put("listArr",listArr);
        map.put("total",total);
        return map;
    }


}
